<?php
namespace Client\Controller;

use Client\Lib\WxPayOrderQuery;
use Client\Lib\WxPayApi;
use Client\Lib\WxPayNotify;
use Zend\Log\Logger;
use Zend\Log\Writer\Stream;
use Client\Common\LoggerHelper;

class NotifyController extends CommonController
{   
    
    public function wechatAction()
    {
        ini_set('date.timezone','Asia/Shanghai');
        error_reporting(E_ERROR);
        
        $logger = new Logger;
        $logger->addWriter(new Stream('data/logs/payment_notify.log'));
        $logger->debug("begin notify");
        
        $notify = new PayNotifyCallBack($this);
        $notify->Handle(false);
        die();
    }
        
    /*
     * for test case,close with private
     */
    public function testPaymentAction()
    {
        $request = $this->getRequest();
        $order_no = $request->getPost('order_no');
        
        $result = array(
            'out_trade_no' => $order_no,
            'transaction_id' => '23534534554',
            'trade_type' => 'JSAPI',
            'trade_channel'=> 'wx'
        );
        
        echo $this->payment($order_no);
        echo 'sdf';
        die();
    }
    
    public function payment($result)
    {       
        $db = $this->getAdapter()->getDriver()->getConnection();
        $db->beginTransaction();
        try
        {
            //订单信息
            $order = $this->getOrderTable()->getByOrderNo($result['out_trade_no']);
            if(empty($order)) {
                throw new \Exception("订单不存在");
            }
             
            //买家信息
            $user = $this->getUserTable()->getById($order->user_id);
            if(empty($user)) {
                throw new \Exception("买家不存在");
            }
             
            //检查余额是否足够
            if ($result['total_fee'] === (int)$order->order_total_price*100) {
                throw new \Exception("支付金额不正确");
            }
    
            //检查订单状态
            if ($order->status != 1) {
                throw new \Exception("订单状态异常");
            }
    
            $order->status = 2;
            $order->transaction_id = $result['transaction_id'];
            $order->trade_type = $result['trade_type'];
            $order->trade_channel = 'wx';
            $order->save();
    
            $db->commit();
            return true;
        }
        catch(\Exception $e)
        {
            $db->rollBack();
            LoggerHelper::client_exception($e);
            return false;
        }
    }
}



class PayNotifyCallBack extends WxPayNotify
{
    private $controller;
    
    function __construct(NotifyController $controller) {
        $this->controller = $controller;
    }
    
    //查询订单
    public function Queryorder($transaction_id)
    {
        $input = new WxPayOrderQuery();
        $input->SetTransaction_id($transaction_id);
        $result = WxPayApi::orderQuery($input);
        
        
        $logger = new Logger;
        $logger->addWriter(new Stream('data/logs/payment_notify.log'));
        $logger->debug("query:" . json_encode($result));

        if(array_key_exists("return_code", $result)
            && array_key_exists("result_code", $result)
            && $result["return_code"] == "SUCCESS"
            && $result["result_code"] == "SUCCESS")
        {
            $this->controller->payment($result);
            return true;
        }
        return false;
    }

    //重写回调处理函数
    public function NotifyProcess($data, &$msg)
    {
        $logger = new Logger;
        $logger->addWriter(new Stream('data/logs/payment_notify.log'));
        $logger->debug("call back:" . json_encode($data));

        $notfiyOutput = array();

        if(!array_key_exists("transaction_id", $data)){
            $msg = "输入参数不正确";
            return false;
        }
        //查询订单，判断订单真实性
        if(!$this->Queryorder($data["transaction_id"])){
            $msg = "订单查询失败";
            return false;
        }
        return true;
    }    
    
}



